home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / TCL1 / CTRACE2_ / CLOGPANO.C < prev    next >
Text File  |  1990-12-10  |  6KB  |  179 lines

  1. /*****     
  2.     from CTRACE: A MESSAGE LOGGING CLASS
  3.     by William D. Cramer in Dr. Dobbs Journal #170, p. 44-55, 116-120.
  4. *****/
  5.  
  6. /** CLogPanorama.c -- Methods for a CLogPanorama class object. **/
  7. #include "CLogPanorama.h"                /* defines log class */
  8.  
  9. /** ILogPanorama -- Initializes an instance of the log panorama class. **/
  10. void CLogPanorama::ILogPane
  11.     (
  12.     short records,            /* number of records in LogList */
  13.     CBureaucrat    *aSupervisor,    /* in-charge for this panorama */
  14.     CWindow *aWindow        /* window object to place pane into */
  15.     )
  16. {
  17. FontInfo
  18.     fontParms;            /* paramaters of selected font */
  19. short    
  20.     lineSpace,            /* pixels per line */
  21.     charSpace;            /* pixels per widest character */
  22. Rect    
  23.     maxWindowRect,            /* maximum growth of log window */
  24.     marginRect;            /* inside margins of viewable area */
  25. CScrollPane
  26.     *theScrollPane;         /* pane associated with panorama */
  27.     
  28. /* Set drawing parameters and adjust record size, if necessary. **/
  29. aWindow->Prepare ();
  30. TextFont (LOGPANE_FONT);
  31. TextSize (LOGPANE_FONT_SIZE);
  32. GetFontInfo (&fontParms);
  33. lineSpace = fontParms.ascent+fontParms.descent+fontParms.leading;
  34. charSpace = fontParms.widMax;
  35. if ( ((long)records*(long)lineSpace) > (long)INT_MAX)
  36.     records = INT_MAX / lineSpace;
  37. SetRect (&maxWindowRect, MIN_WSIZE, MIN_WSIZE, 
  38.         (MAX_LOGREC_CHAR * charSpace) + SBARSIZE, 
  39.         (records * lineSpace) + SBARSIZE);
  40. aWindow->SetSizeRect (&maxWindowRect);
  41.  
  42. /* Initialize Panorama's ScrollPane, set scroll units to the defaulted 
  43. ** values, and attach the Panorama to the ScrollPane. */
  44. theScrollPane = new (CScrollPane);
  45. theScrollPane->IScrollPane(aWindow, this, 0, 0, 0, 0,sizELASTIC, sizELASTIC,TRUE, TRUE, TRUE);
  46. theScrollPane->FitToEnclFrame (TRUE, TRUE);
  47. theScrollPane->SetSteps (LOGPANE_HORZ_SCROLL, LOGPANE_VERT_SCROLL);
  48.  
  49. /* Initialize Panarama to include maximum chars wide and maximum records tall,
  50. ** set the Panarama units to one char wide and one char tall. */
  51. CPanorama::IPanorama(theScrollPane, aSupervisor, MAX_LOGREC_CHAR, 
  52.         records, 0, 0, sizELASTIC, sizELASTIC);
  53. SetScales (charSpace, lineSpace);
  54. FitToEnclosure (TRUE, TRUE);
  55. theScrollPane->InstallPanorama (this);
  56.  
  57. /*  Create the LogList and initialize. */
  58. itsLogList = new (CLogList);
  59. itsLogList->ILogList (records);
  60. }
  61.  
  62. /** Draw() -- Refreshes the visible portion of the window. **/ 
  63. void CLogPanorama::Draw
  64.     (
  65.     Rect *drawRect        /* portion of window to refresh */
  66.     )
  67. {
  68. short    
  69.     firstRec,        /* record number of first visible line */
  70.     hScale,         /* how many pixels wide is a character? */
  71.     lastRec,        /* record number of last line */
  72.     totalRec,        /* total number of records in LogList */
  73.     vScale;         /* how many pixels tall is a line? */ 
  74. register short
  75.     currRow,        /* window coordinates of current row */
  76.     rec;            /* loop counter */
  77. char 
  78.     buff[MAX_LOGREC_CHAR];    /* buffer for fetching log records */
  79. /*  First, translate draw rectangle to records. **/
  80. GetScales (&hScale, &vScale);
  81. totalRec = (short)itsLogList->GetNumItems ();
  82. firstRec = (drawRect->top / vScale);
  83. if (firstRec == 0)
  84.     firstRec = 1;
  85. lastRec = (drawRect->bottom / vScale) + 1;
  86. if (lastRec > totalRec)
  87.     lastRec = totalRec;
  88. /*  Refresh all of visible lines. **/
  89. Prepare ();
  90. for (rec=firstRec, currRow=firstRec*vScale;
  91.         rec<=lastRec;
  92.         rec++, currRow+=vScale)
  93.     {
  94.     itsLogList->GetString (rec, buff);
  95.     MoveTo (LOGPANE_INSET, currRow);
  96.     DrawString (CtoPstr(buff));
  97.     }
  98. }
  99.  
  100. /** AddString() -- Adds a new string to panorama. **/
  101. void CLogPanorama::AddString
  102.     (
  103.     char *theString        /* null-terminated string to add */
  104.     )
  105. {
  106. Rect
  107.     frameRect;        /* interior of current frame */
  108. short
  109.     listLimits,        /* maximum the LogList will hold */
  110.     hSpan,            /* the horizontal span of frame */
  111.     vSpan,            /* the vertical span of frame */
  112.     hScale,         /* horizontal pixels in panarama unit */
  113.     vScale;         /* vertical pixels in panarama unit */
  114. Point
  115.     topRecord,        /* LogList record number of top row */
  116.     bottomRecord,        /* LogList record number of bottom row */
  117.     newRecord,        /* LogList record number of new row */
  118.     currPosition,        /* panorama coordinates of top/left frame */
  119.     recPosition;        /* panorama coordinates of new string */
  120. /*  Add the record to the LogList. */
  121. itsLogList->AddString (theString);
  122. /*  Get coordinates of current frame and calculate tentative coordinates for 
  123. newly added record. */
  124. GetPosition (&currPosition);
  125. GetFrameSpan (&hSpan, &vSpan);
  126. GetScales (&hScale, &vScale);
  127. topRecord.v = currPosition.v + 1;
  128. bottomRecord.v = topRecord.v + vSpan - 1;
  129. newRecord.v = (short)itsLogList->GetNumItems ();
  130. newRecord.h = currPosition.h;
  131.  
  132. /* Determine where we are in reference to bottom of screen and of list. **/
  133. if (newRecord.v > (bottomRecord.v+1) )
  134.     {
  135.     /* bottom record isn't visible */
  136.     currPosition.v = newRecord.v - vSpan;
  137.     ScrollTo (currPosition, FALSE);
  138.     GetInterior (&frameRect);
  139.     Prepare ();
  140.     EraseRect (&frameRect);
  141.     }
  142. else
  143.     {
  144.     /* bottom record is visible */
  145.     listLimits = itsLogList->GetMaxRecordCount ();
  146.     if (bottomRecord.v < listLimits)
  147.         {
  148.         /* room in list--create blank line if necessary */
  149.         if (newRecord.v == (bottomRecord.v + 1) )
  150.             {
  151.             Scroll (0, 1, TRUE);
  152.             SetRect (&frameRect, newRecord.h*hScale, (newRecord.v-1)*vScale,(newRecord.h+hSpan)*hScale, (newRecord.v)*vScale);
  153.             }
  154.         else
  155.            SetRect (&frameRect, newRecord.h*hScale, (newRecord.v-1)*vScale,
  156.                    (newRecord.h+hSpan-1)*hScale, (newRecord.v)*vScale);
  157.         }    
  158.     else if (bottomRecord.v > listLimits)
  159.         {
  160.         currPosition.v = newRecord.v - vSpan;
  161.         ScrollTo (currPosition, FALSE);
  162.         GetInterior (&frameRect);
  163.         Prepare ();
  164.         EraseRect (&frameRect);
  165.         }
  166.     else
  167.         {
  168.       /* bottom of pane=limit of list, so do our own scrolling */
  169.         Prepare ();
  170.         GetInterior (&frameRect);
  171.         ScrollRect (&frameRect, 0, -vScale, gUtilRgn);
  172.      SetRect (&frameRect, bottomRecord.h*hScale, (bottomRecord.v-1)*vScale,(bottomRecord.h+hSpan-1)*hScale, (bottomRecord.v)*vScale);
  173.         EraseRect (&frameRect);
  174.         }
  175.     }        
  176. Draw (&frameRect);
  177. itsScrollPane->Calibrate();
  178. }
  179.